import { snakeCase } from 'lodash-es';
import type {
    BaseModelConstructor,
    EzModelOptions,
    // EzModelPool,
    ModelParams,
    TreeField
} from '../types';
import {IBaseModel} from "../types";

// export const getEzModelPool = (): EzModelPool => {
//     // 返回空对象，因为不再使用EZ_MODEL_POOL
//     return {}
// }

export const useModelOptions = <T extends IBaseModel<T>>(constructor: BaseModelConstructor<T>): EzModelOptions<T> => {
    // 直接从构造函数获取模型状态
    return getModelState(constructor)
}


export const setModelState = <T extends IBaseModel<T>>(constructor: BaseModelConstructor<T>, state: ModelParams<T>): BaseModelConstructor<T> => {
    const modelName = state.name || constructor.name
    const snakeCaseName: string = snakeCase(modelName)

    // 创建状态副本避免修改原始对象
    const processedState = { ...state }

    // 设置默认权限和API路径
    if (!processedState.perms) {
        processedState.perms = snakeCaseName.replace(/_+/g, '-')
    }
    if (!processedState.api) {
        processedState.api = snakeCaseName.replace(/_+/g, '/')
    }

    // 处理树形结构配置
    const { tree } = processedState
    const defaultTreeField: TreeField<T> = {
        pid: 'parentId',
        children: 'children'
    }
    if (tree === true) {
        processedState.tree = defaultTreeField
    } else if (tree) {
        processedState.tree = {
            ...defaultTreeField,
            ...tree
        }
    }

    // 确保每个类都有自己独立的$OPTS属性，而不是共享父类的属性
    // 检查当前构造函数是否有自己的$OPTS属性（不是从原型链继承的）
    if (!constructor.hasOwnProperty('$OPTS')) {
        // 使用Object.defineProperty确保$OPTS属性直接定义在当前构造函数上
        Object.defineProperty(constructor, '$OPTS', {
            value: {} as EzModelOptions<T>,
            writable: true,
            enumerable: true,
            configurable: true
        })
    }

    // 处理模型键
    const baseModelKey = 'BaseModel'
    const opts = constructor.$OPTS! // 此时$OPTS已经确保存在
    if (!opts.modelKey) {
        opts.modelKey = baseModelKey
    } else if (opts.modelKey === baseModelKey && modelName !== baseModelKey) {
        opts.modelKey = modelName
    }

    // 将所有state属性绑定到constructor.$OPTS上
    Object.keys(processedState).forEach(key => {
        try {
            (opts as any)[key] = (processedState as any)[key]
        } catch (e) {
            console.warn(`无法设置$OPTS属性 ${key}:`, e instanceof Error ? e.message : String(e))
        }
    })

    return constructor
}

export const getModelState = <T extends IBaseModel<T>>(constructor: BaseModelConstructor<T>): EzModelOptions<T> => {
    // 优先检查当前构造函数是否有自己的$OPTS属性（不是从原型链继承的）
    if (constructor.hasOwnProperty('$OPTS') && constructor.$OPTS) {
        return constructor.$OPTS
    }

    // 如果当前类没有自己的$OPTS属性，返回空对象
    return {} as EzModelOptions<T>
}
